const createError = require("http-errors")
const express = require("express")
const path = require("path")
const logger = require("morgan")
const cors = require("cors")
const joi = require("joi")
const bodyParser = require("body-parser")

// 导入路由模块
const publicRouter = require("./routes/reception/user")
const userinfoRouter = require("./routes/reception/userinfo")
const commonRouter = require("./routes/common")
const adminRouter = require("./routes/manage/admin")
const announceRouter = require("./routes/manage/announce")
const repairTypeRouter = require("./routes/manage/repair_type")
const repairerTypeRouter = require("./routes/manage/repairer_type")
const repairerRouter = require("./routes/manage/repairer")
const studentRouter = require("./routes/manage/student")
const mFeedbackRouter = require("./routes/manage/feedback")
const rFeedbackRouter = require("./routes/reception/feedback")
const mRepairRouter = require("./routes/manage/repair")
const rRepairRouter = require("./routes/reception/repair")
const classRouter = require("./routes/manage/class")
const facultyRouter = require("./routes/manage/faculty")
const gradeRouter = require("./routes/manage/grade")
const areaRouter = require("./routes/manage/area")

const app = express() // 创建 express 的服务器实例

// 自定义发送
app.use((req, res, next) => {
  res.successSend = (message, code = 10000, data) => {
    res.send({
      success: true,
      code,
      message: message ? message : "请求成功",
      data,
    })
  }
  // err 的值可能是一个错误对象，也可能是一个描述错误的字符串
  res.errSend = (err, code = 10003) => {
    res.send({
      success: false,
      code,
      message: err instanceof Error ? err.message : err || "操作失败！",
    })
  }
  next()
})

const config = require("./config") // 导入配置文件
app.use(cors()) // 配置 cors 跨域
const { expressjwt } = require("express-jwt") // 解析 token 的中间件
app.use(
  expressjwt({ secret: config.jwtSecretKey, algorithms: ["HS256"] }).unless({
    path: [/^\/user\//],
  })
)

// 配置全局变量 app.js作用域下所有文件都可以访问common中的db和RunSQL
require(process.cwd() + "/common/sql")

app.use(express.urlencoded({ extended: false })) // 配置解析表单数据的中间件
app.use(bodyParser.json()) //数据JSON类型
app.use(bodyParser.urlencoded({ extended: false })) //解析post请求数据

// 查看引擎设置
app.set("views", path.join(__dirname, "views"))
app.set("view engine", "ejs")

app.use(logger("dev"))
app.use(express.static(path.join(__dirname, "public")))

// 公开路由
app.use("/user", publicRouter)

const { userStatement } = require("./service/common/user")
app.use(async (req, res, next) => {
  try {
    const userinfo = req.auth
    if (userinfo.id) {
      if (userinfo.type !== 1) {
        const sqlStr = userStatement(userinfo.type).idSelect(userinfo.id, 'state')
        let results = await RunSQL(sqlStr)
        if (results.length !== 1) return res.successSend("获取个人信息失败！", 10005) // 执行语句成功，但获取到的数据条数非 1
        if (results[0].state) {
          res.status(402)
          return res.errSend("账号已锁定！", 10011)
        }
      }
      next() // pass control to the next handler
    }
  } catch (error) {
    return res.errSend(error)
  }
})

// 公共路由
app.use("/userinfo", userinfoRouter)
app.use("/common", commonRouter)

// 学生和维修人员路由

app.use("/reception/feedback", rFeedbackRouter)
app.use("/reception/repair", rRepairRouter)



// 管理员路由
app.use("/student", studentRouter)
app.use("/repairer", repairerRouter)
app.use("/announce", announceRouter)
app.use("/admin", adminRouter)
app.use("/manage/feedback", mFeedbackRouter)
app.use("/manage/repair", mRepairRouter)
app.use("/class", classRouter)
app.use("/faculty", facultyRouter)
app.use("/grade", gradeRouter)

app.use("/repair_type", repairTypeRouter)
app.use("/repairer_type", repairerTypeRouter)
app.use("/area", areaRouter)

// 捕获404并转发给错误处理程序
app.use((req, res, next) => {
  next(createError(404))
})

// 错误处理程序
app.use((err, req, res, next) => {
  // 设置局部变量，只在开发中提供错误
  res.locals.message = err.message
  res.locals.error = req.app.get("env") === "development" ? err : {}
  // 捕获身份认证失败的错误
  if (err.name === "UnauthorizedError") {
    res.status(401)
    return res.errSend("身份认证失败！", 10006)
  }
  if (err.message !== 'Not Found') {
    console.log(err)
    res.status(400)
    return res.errSend(err.message, 10011)
  }
})

module.exports = app
